package com.dc.java8._1_lambda;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * Description: lambda 入门篇
 * @author: gdc
 * @date: 2021/4/10
 * @version 1.0
 */
public class LambdaTest1 {

	String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka", "David Ferrer",
			"Roger Federer", "Andy Murray",  "Tomas Berdych", "Juan Martin Del Potro",
			"Richard Gasquet", "John Isner"};

	@Test
	public void test1() {
		List<String> strList = Arrays.asList(players);
		
		// 以前的循环
		for (String string : strList) {
			System.out.println(string + ";");
		}
		
		System.out.println("\r----------------------分割线------------------------");
		
		// lambda 表达式
		strList.forEach((str) -> System.out.println(str + ";"));
		
		System.out.println("\r----------------------分割线------------------------");

		// java8 中 :: 操作符
		strList.forEach(System.out::println );
	}


	/**
	 *  实现 String 的排序功能
	 */
	@Test
	public void test2() {
		for (int i = 0; i < players.length; i++) {
			System.out .println(players[i]);
		}

		System.out.println("---------------分隔符--------------------");

		// <1> 使用匿名内部类根据 name 排序 players
		Arrays.sort(players, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return (o1.compareTo(o2));
			}
		});

		for (int i = 0; i < players.length; i++) {
			System.out .println(players[i]);
		}
		System.out.println("---------------分隔符--------------------");

		// <2>使用 lambda 实现上面的功能
		Comparator<String> sortName = (String s1 , String s2) -> (s1.compareTo(s2));
		Arrays.sort(players,sortName);

		// <3>也可以使用如下方式，实现name的排序
		Arrays.sort(players, (s1, s2) -> (s1.compareTo(s2)));

		for (int i = 0; i < players.length; i++) {
			System.out .println(players[i]);
		}
	}

	/**
	 * 根据 字符串的长度进行排序
	 *
	 * 两种比较器Comparable和Comparator，后者相比前者有如下优点：
	 * 1、如果实现类没有实现Comparable接口，又想对两个类进行比较（或者实现类实现了Comparable接口，但是对compareTo方法内的比较算法不满意），
	 *  那么可以实现Comparator接口，自定义一个比较器，写比较算法
	 * 2、实现Comparable接口的方式比实现Comparator接口的耦合性 要强一些，
	 *  如果要修改比较算法，要修改Comparable接口的实现类，而实现Comparator的类是在外部进行比较的，不需要对实现类有任何修 改。
	 *  从这个角度说，其实有些不太好，尤其在我们将实现类的.class文件打成一个.jar文件提供给开发者使用的时候。实际上实现Comparator 接口的方式后面会写到就是一种典型的策略模式。
	*/
	public void test3() {
		// <1> 最原始的对两个字符串的长度进行排序
		Arrays.sort(players, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return  -o1.length() + o2.length();
			}
		});

		// <2> lambda
		Comparator<String> comp = (String s1,String s2) -> (s1.length() - s2.length());
		Arrays.sort(players, comp);

		// <3> lambda
		Arrays.sort(players, (String s1,String s2) -> (s1.length() - s2.length()));

		for (String name : players) {
			System.out.println(name);
		}
	}
}
